home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / programm.ing / xaes_new.lzh / CREATE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-27  |  22.5 KB  |  876 lines

  1. /********************************************************************
  2.  *                                                                2.01*
  3.  *    XAES: Window creation routines                                    *
  4.  *    Code by Ken Hollis, GNU C Extensions by Sascha Blank            *
  5.  *                                                                    *
  6.  *    Copyright (c) 1994, Bitgate Software.  All Rights Reserved.        *
  7.  *                                                                    *
  8.  *    Again, most of these routines were taken from WinLIB PRO, but    *
  9.  *    they have been revamped and greatly optimized.  Any convoluted    *
  10.  *    code is my fault.  :-)                                            *
  11.  *                                                                    *
  12.  ********************************************************************/
  13.  
  14. #include <string.h>
  15. #include <stddef.h>
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <stdarg.h>
  19.  
  20. #include "xaes.h"
  21. #include "treecopy.h"
  22.  
  23. GRECT desk;
  24. WINDOW *WindowChain;
  25. int Life, Return, VDIhandle, Ap_ID;
  26. OBJECT *wl_menubar = NULL;
  27.  
  28. int gr_cw, gr_ch, gr_bw, gr_bh;
  29. int small_font, large_font, color_font;
  30. int num_colors, num_planes;
  31. int image_w, image_h, big_img;
  32. char *prgnameheader;
  33.  
  34. WOWNERS    owned_winds[MAX_WINDOWS];
  35.  
  36. #ifdef TURBO_C
  37. #pragma warn -pia
  38. #endif
  39.  
  40. /*
  41.  *    A complete replacement for wind_set, only smarter.
  42.  */
  43. GLOBAL int WWindSet(WINDOW *win, int wi_sfield, ...)
  44. {
  45.     va_list    argptr;
  46.     int wi_sw1, wi_sw2, wi_sw3, wi_sw4;
  47.     long wi_sl1;
  48.  
  49.     switch (wi_sfield) {
  50.         case WF_TOP:
  51.             wind_set(win->handle, WF_TOP);
  52.             if (win->prev)                                    /* Bring window to top of WindowChain */
  53.                 win->prev->next = win->next;
  54.  
  55.             win->next->prev = win->prev;
  56.         
  57.             if (WindowChain == win)
  58.                 WindowChain = win->next;
  59.         
  60.             WindowChain->prev = win;
  61.             win->next = WindowChain;
  62.             win->prev = NULL;
  63.             WindowChain = win;
  64.             return TRUE;
  65.  
  66.         case WF_BEVENT:
  67.         case WF_MINIMIZE:
  68.         case WF_UNUNTOPPABLE:
  69.             va_start(argptr, wi_sfield);
  70.             wi_sw1 = va_arg(argptr, int);
  71.             va_end(argptr);
  72.  
  73.             if (win)
  74.                 switch (wi_sfield) {
  75.                     case WF_BEVENT:
  76.                         if (AES_VERSION >= 0x0400)
  77.                             wind_set(win->handle, WF_BEVENT, wi_sw1 ? 1 : 0);
  78.  
  79.                         if (xaes.config2 & X_BACKGROUND) {
  80.                             if (wi_sw1)
  81.                                 win->state |= W_BEVENT;
  82.                             else
  83.                                 win->state &= ~W_BEVENT;
  84.                             return TRUE;
  85.                         } else
  86.                             return FALSE;
  87.  
  88.                     case WF_MINIMIZE:
  89.                         if (wi_sw1)
  90.                             win->state |= W_MINIMIZED;
  91.                         else
  92.                             win->state &= ~W_MINIMIZED;
  93.  
  94.                         WWindSet(win, WF_CURRXYWH, -1, -1, -1, win->size.g_h);
  95.                         return TRUE;
  96.  
  97.                     case WF_UNUNTOPPABLE:
  98.                         if (wi_sw1)
  99.                             win->state |= W_UNUNTOPPABLE;
  100.                         else
  101.                             win->state &= ~W_UNUNTOPPABLE;
  102.  
  103.                         WWindSet(win, WF_TOP);
  104.                         return TRUE;
  105.                 }
  106.  
  107.         case WF_TIMER:
  108.             va_start(argptr, wi_sfield);
  109.             wi_sw1 = va_arg(argptr, int);
  110.             va_end(argptr);
  111.  
  112.             if ((wi_sw1) && (win))
  113.                 win->state |= W_TIMER;
  114.             else
  115.                 win->state &= ~W_TIMER;
  116.  
  117.             return TRUE;
  118.  
  119.         case WF_DIALOG:
  120.             va_start(argptr, wi_sfield);
  121.             wi_sw1 = va_arg(argptr, int);
  122.             va_end(argptr);
  123.  
  124.             if ((wi_sw1) && (win))
  125.                 win->state |= W_DIALOG;
  126.             else
  127.                 win->state &= ~W_DIALOG;
  128.  
  129.             return TRUE;
  130.  
  131.         case WF_UNSIZABLE:
  132.             va_start(argptr, wi_sfield);
  133.             wi_sw1 = va_arg(argptr, int);
  134.             va_end(argptr);
  135.  
  136.             if ((wi_sw1) && (win))
  137.                 win->state |= W_UNSIZABLE;
  138.             else
  139.                 win->state &= ~W_UNSIZABLE;
  140.  
  141.             return TRUE;
  142.  
  143.         case WF_CUSTOMWIN:
  144.             va_start(argptr, wi_sfield);
  145.             wi_sw1 = va_arg(argptr, int);
  146.             va_end(argptr);
  147.  
  148.             if ((wi_sw1) && (win))
  149.                 win->style |= W_CUSTOMWINDOW;
  150.             else
  151.                 win->style &= ~W_CUSTOMWINDOW;
  152.  
  153.             return TRUE;
  154.  
  155.         case WF_ICONIFIED:
  156.             va_start(argptr, wi_sfield);
  157.             wi_sw1 = va_arg(argptr, int);
  158.             va_end(argptr);
  159.  
  160.             if ((wi_sw1) && (win) && (win->iconify)) {
  161.                 win->size.g_w = win->iconify->ob_width;
  162.                 win->size.g_h = win->iconify->ob_height;
  163.  
  164.                 win->oldstate = win->state;
  165.                 win->oldstyle = win->style;
  166.                 win->oldkind = win->kind;
  167.  
  168.                 win->style = 0;
  169.                 win->state = W_OPEN | W_BEVENT | W_DIALOG | W_ICONIFIED;
  170.                 win->kind = NAME|MOVER;
  171.  
  172.                 win->iconify->ob_x = win->tree->ob_x;
  173.                 win->iconify->ob_y = win->tree->ob_y;
  174.  
  175.                 win->oldsize.g_x = win->size.g_x;
  176.                 win->oldsize.g_y = win->size.g_y;
  177.                 win->oldsize.g_w = win->size.g_w;
  178.                 win->oldsize.g_h = win->size.g_h;
  179.  
  180.                 WMoveWindow(win, -1, -1, -1, -1);
  181.  
  182.                 WGrafMouse(ARROW);
  183.                 wind_close(win->handle);
  184.                 wind_delete(win->handle);
  185.  
  186.                 wind_create(win->kind, win->size.g_x, win->size.g_y, win->iconify->ob_width, win->iconify->ob_height + 13);
  187.  
  188.                 WWindSet(win, WF_KIND, win->kind);
  189.                 wind_open(win->handle, win->size.g_x, win->size.g_y, win->iconify->ob_width, win->iconify->ob_height + 13);
  190.  
  191.                 WWindSet(win, WF_CURRXYWH, win->size.g_x, win->size.g_y, win->iconify->ob_width, win->iconify->ob_height + 13);
  192.                 WWindSet(win, WF_BEVENT, 1);
  193.                 WWindSet(win, WF_DIALOG, 1);
  194.  
  195.                 WRedrawWindow(win, win->size.g_x, win->size.g_y, win->iconify->ob_width, win->iconify->ob_height + 13);
  196.                 vswr_mode(VDIhandle, MD_XOR);
  197.             }
  198.  
  199.             return TRUE;
  200.  
  201.         case WF_UNICONIFIED:
  202.             va_start(argptr, wi_sfield);
  203.             wi_sw1 = va_arg(argptr, int);
  204.             va_end(argptr);
  205.  
  206.             if ((wi_sw1) && (win) && (win->iconify)) {
  207.                 win->size.g_w = win->tree->ob_width;
  208.                 win->size.g_h = win->tree->ob_height;
  209.  
  210.                 win->state = win->oldstate;
  211.                 win->style = win->oldstyle;
  212.                 win->kind = win->oldkind;
  213.  
  214.                 win->state &= ~W_ICONIFIED;
  215.  
  216.                 win->tree->ob_x = win->iconify->ob_x;
  217.                 win->tree->ob_y = win->iconify->ob_y;
  218.  
  219.                 WGrafMouse(ARROW);
  220.                 wind_close(win->handle);
  221.                 wind_delete(win->handle);
  222.  
  223.                 win->size.g_x = win->oldsize.g_x;
  224.                 win->size.g_y = win->oldsize.g_y;
  225.                 win->size.g_w = win->oldsize.g_w;
  226.                 win->size.g_h = win->oldsize.g_h;
  227.  
  228.                 if (win->style & W_CUSTOMWINDOW)
  229.                     wind_create(0, win->wind->ob_x, win->wind->ob_y, win->wind->ob_width, win->wind->ob_height);
  230.                 else
  231.                     wind_create(win->kind, win->size.g_x, win->size.g_y, win->size.g_w, win->size.g_h);
  232.  
  233.                 if (!(win->style & W_CUSTOMWINDOW))
  234.                     WWindSet(win, WF_KIND, win->kind);
  235.  
  236.                 wind_open(win->handle, win->size.g_x, win->size.g_y, win->size.g_w, win->size.g_h);
  237.  
  238.                 WWindSet(win, WF_CURRXYWH, win->size.g_x, win->size.g_y, win->size.g_w, win->size.g_h);
  239.                 WWindSet(win, WF_BEVENT, 1);
  240.                 WWindSet(win, WF_DIALOG, 1);
  241.  
  242.                 vswr_mode(VDIhandle, MD_XOR);
  243.             }
  244.  
  245.             return TRUE;
  246.  
  247.         case WF_NAME:
  248.         case WF_INFO:
  249.             va_start(argptr, wi_sfield);
  250.             wi_sl1 = va_arg(argptr, long);
  251.             va_end(argptr);
  252.  
  253.             if (win)
  254.                 switch (wi_sfield) {
  255.                     case WF_NAME:
  256.                         if (win->state & W_DIALOG)
  257.                             sprintf(win->title, "[ %s%s ]", prgnameheader, wi_sl1);
  258.                         else
  259.                             sprintf(win->title, "%s%s", prgnameheader, wi_sl1);
  260.  
  261.                         return wind_set(win->handle, WF_NAME, win->title);
  262.  
  263.                     case WF_INFO:
  264.                         if (wi_sl1 != 0L)
  265.                             strncpy(win->info, (char *) wi_sl1, 128);
  266.                         else
  267.                             strncpy(win->info, " ", 128);
  268.  
  269.                         return wind_set(win->handle, WF_INFO, win->info);
  270.                 }
  271.  
  272.         default:
  273.             va_start(argptr, wi_sfield);
  274.             wi_sw1 = va_arg(argptr, int);
  275.             wi_sw2 = va_arg(argptr, int);
  276.             wi_sw3 = va_arg(argptr, int);
  277.             wi_sw4 = va_arg(argptr, int);
  278.             va_end(argptr);
  279.  
  280.             if (win)
  281.                 switch (wi_sfield) {
  282.                     case WF_CURRXYWH:
  283.                         WMoveWindow(win, wi_sw1, wi_sw2, wi_sw3, wi_sw4);
  284.                         return TRUE;
  285.  
  286.                     case WF_WORKXYWH:        /* Can't set work! */
  287.                         return FALSE;
  288.  
  289.                     default:
  290.                         return wind_set(win->handle, wi_sfield, wi_sw1, wi_sw2, wi_sw3, wi_sw4);
  291.                 }
  292.     }
  293.  
  294.     return FALSE;
  295. }
  296.  
  297. /*
  298.  *    A replacement for wind_get, only better.
  299.  */
  300. GLOBAL int WWindGet(WINDOW *win, int wi_gfield, ...)
  301. {
  302.     va_list    argptr;
  303.     int ret, *wi_gw1, *wi_gw2, *wi_gw3, *wi_gw4;
  304.     
  305.     va_start(argptr, wi_gfield);
  306.     wi_gw1 = va_arg(argptr, int *);
  307.     wi_gw2 = va_arg(argptr, int *);
  308.     wi_gw3 = va_arg(argptr, int *);
  309.     wi_gw4 = va_arg(argptr, int *);
  310.     va_end(argptr);
  311.  
  312.     if (win)
  313.         switch (wi_gfield) {
  314.             case WF_WORKXYWH:
  315.                 {
  316.                     int x, y, w, h;
  317.  
  318.                     if ((win->handle == 0) && (win->state & W_OPEN) && !(win->style & W_CUSTOMWINDOW))
  319.                         ret = wind_get(win->handle, WF_WORKXYWH, wi_gw1, wi_gw2, wi_gw3, wi_gw4);
  320.                     else
  321.                         if (win->state & W_OPEN)
  322.                             if (ret = wind_get(win->handle, WF_WORKXYWH, &x, &y, &w, &h)) {
  323.                                 if (win->style & W_CUSTOMWINDOW) {
  324.                                     x += (win->wind_type == WC_WINDOW) ? win->wind[25].ob_x : win->wind[32].ob_x;
  325.                                     y += (win->wind_type == WC_WINDOW) ? win->wind[25].ob_y : win->wind[32].ob_y;
  326.                                     w = (win->wind_type == WC_WINDOW) ? win->wind[25].ob_width : win->wind[32].ob_width;
  327.                                     h = (win->wind_type == WC_WINDOW) ? win->wind[25].ob_height : win->wind[32].ob_height;
  328.                                 }
  329.  
  330.                                 wi_gw1 = (int *) x;
  331.                                 wi_gw2 = (int *) y;
  332.                                 wi_gw3 = (int *) w;
  333.                                 wi_gw4 = (int *) h;
  334.  
  335.                                 ret = TRUE;
  336.                             }
  337.                 }
  338.  
  339.                 return ret;
  340.  
  341.             default:
  342.                 if (win->state & W_OPEN)
  343.                     return wind_get(win->handle, wi_gfield, wi_gw1, wi_gw2, wi_gw3, wi_gw4);
  344.         }
  345.  
  346.     return FALSE;
  347. }
  348.  
  349. /*
  350.  *    This reserves screen memory for the window about to be opened,
  351.  *    and checks internal handles to make sure it can be opened.
  352.  */
  353. GLOBAL int WOpenWindow(WINDOW *win)
  354. {
  355.     if (win) {
  356.         if (!(win->state & W_OPEN) && !(wind_open(win->handle, win->size.g_x, win->size.g_y, win->size.g_w, win->size.g_h)))
  357.             return FALSE;
  358.         else
  359.             win->state |= W_OPEN;                /* Set state to "open" */
  360.  
  361.         owned_winds[win->handle].handle = win->handle;
  362.         owned_winds[win->handle].owner  = Ap_ID;
  363.  
  364.         return TRUE;
  365.     } else
  366.         return FALSE;
  367. }
  368.  
  369. /*
  370.  *    This closes a window without killing it.
  371.  */
  372. GLOBAL void WCruelCloseWindow(WINDOW *win, BOOL icon)
  373. {
  374.     UNUSED(icon);
  375.  
  376.     if (!win)
  377.         win = WindowChain;
  378.  
  379.     if (win)
  380.         if (win->next && win->state & W_OPEN && wind_close(win->handle)) {
  381.             WGrafMouse(ARROW);
  382.             win->state &= ~W_OPEN;
  383.  
  384.             if ((win->state & W_ICONIFIED) && (win->iconify)) {
  385.                 graf_shrinkbox(desk.g_w / 2, desk.g_h / 2, 2, 2, win->size.g_x, win->size.g_y, win->iconify->ob_width, win->iconify->ob_height + 13);
  386.                 vswr_mode(VDIhandle, MD_XOR);
  387.             } else {
  388.                 graf_shrinkbox(desk.g_w / 2, desk.g_h / 2, 2, 2, win->size.g_x, win->size.g_y, win->size.g_w, win->size.g_h);
  389.                 vswr_mode(VDIhandle, MD_XOR);
  390.             }
  391.  
  392.             return;
  393.         }
  394. }
  395.  
  396. /*
  397.  *    This gives the signal to kill (delete) a window.
  398.  */
  399. GLOBAL void WKillWindow(WINDOW *win)
  400. {
  401.     int msg_buf[8];
  402.  
  403.     if (!win)
  404.         win = WindowChain;
  405.  
  406.     if (win)
  407.         if (win->next) {
  408.             msg_buf[0] = WM_KILL;
  409.             msg_buf[1] = Ap_ID;
  410.             msg_buf[2] = 0;
  411.             msg_buf[3] = win->handle;
  412.     
  413.             WMsgWindow(win, msg_buf);
  414.         }
  415. }
  416.  
  417. /*
  418.  *    This creates the window on the screen, but does not draw it.
  419.  */
  420. GLOBAL int WWindCreate(WINDOW *win)
  421. {
  422.     if (win)
  423.         if (win->style & W_CUSTOMWINDOW) {
  424.             WWindAdjust(win);
  425.             return (wind_create(0, win->size.g_x, win->size.g_y, win->size.g_w, win->size.g_h));
  426.         } else
  427.             return (wind_create(win->kind, win->size.g_x, win->size.g_y, win->size.g_w, win->size.g_h));
  428.     else
  429.         return FALSE;
  430. }
  431.  
  432. /*
  433.  *    This creates an object as defined in the XAES documentation, and
  434.  *    online help.  I'm not about to document every feature of this
  435.  *    routine; it would take a chapter in a book.
  436.  */
  437. GLOBAL void *WCreateObject(int type, ...)
  438. {
  439.     va_list    argptr;
  440.     WINDOW *ptr;
  441.  
  442.     if (type == WC_WINDOW) {
  443.         int state, style, kind, x, y, w, h, edobject, icon;
  444.         void *WndDispatcher;
  445.         char *title, *info, *icontext;
  446.         OBJECT *object, *iconify;
  447.         CALLS *callbacks;
  448.  
  449.         va_start(argptr, wi_gfield);
  450.         state = va_arg(argptr, int);
  451.         style = va_arg(argptr, int);
  452.         kind = va_arg(argptr, int);
  453.         title = va_arg(argptr, char *);
  454.         info = va_arg(argptr, char *);
  455.         object = va_arg(argptr, OBJECT *);
  456.         WndDispatcher = va_arg(argptr, void *);
  457.         x = va_arg(argptr, int);
  458.         y = va_arg(argptr, int);
  459.         w = va_arg(argptr, int);
  460.         h = va_arg(argptr, int);
  461.         edobject = va_arg(argptr, int);
  462.         iconify = va_arg(argptr, OBJECT *);
  463.         icon = va_arg(argptr, int);
  464.         icontext = va_arg(argptr, char *);
  465.         callbacks = va_arg(argptr, CALLS *);
  466.         va_end(argptr);
  467.  
  468.         UNUSED(style);
  469.  
  470.         if (ptr = (WINDOW *) malloc(sizeof(WINDOW))) {
  471.             int msg_buf[8];
  472.  
  473.             ptr->wind_type = type;
  474.             ptr->state = 0;
  475.             ptr->style = 0;
  476.             ptr->kind = kind;
  477.             ptr->editmode = EDIT_INSERT;
  478.             ptr->edobject = edobject;
  479.  
  480.             ptr->timer.clock = 0L;
  481.             ptr->timer.ev_mtcount = 0;
  482.             ptr->timer.user = NULL;
  483.             ptr->timer.status = T_NOTEXIST;
  484.             ptr->timer.tick_count = 0;
  485.             ptr->infpos = 0;
  486.             ptr->infend = 0;
  487.  
  488.             ptr->callbacks = NULL;
  489.  
  490.             if (callbacks != NULL)
  491.                 ptr->callbacks = callbacks;
  492.  
  493.             if (ptr->edobject != 0) {
  494.                 ptr->edpos = 0;
  495.                 ptr->has_edit = TRUE;
  496.                 ptr->edit_disp = TRUE;
  497.             } else {
  498.                 ptr->edpos = 0;
  499.                 ptr->has_edit = FALSE;
  500.                 ptr->edit_disp = FALSE;
  501.             }
  502.  
  503.             ptr->WndDispatcher = malloc(sizeof(WndDispatcher));
  504.             ptr->WndDispatcher = WndDispatcher;
  505.  
  506.             if (style & W_CUSTOMWINDOW)
  507.                 WWindSet(ptr, WF_CUSTOMWIN, 1);
  508.  
  509.             if (iconify) {
  510.                 ptr->iconify = tree_copy(iconify, C_ICONBLKPOINTER);
  511.  
  512.                 if (icontext) {
  513.                     ptr->iconify[icon].ob_spec.iconblk->ib_ptext = icontext;
  514.                     ptr->icon_num = icon;
  515.                     ptr->icon_text = icontext;
  516.                 } else {
  517.                     ptr->iconify[icon].ob_spec.iconblk->ib_ptext = NULL;
  518.                     ptr->icon_num = icon;
  519.                     ptr->icon_text = NULL;
  520.                 }
  521.             } else {
  522.                 ptr->iconify = NULL;
  523.                 ptr->icon_num = 0;
  524.                 ptr->icon_text = NULL;
  525.             }
  526.  
  527.             {
  528.                 int x2, y2, w2, h2;
  529.  
  530.                 ptr->tree = tree_copy(object, C_TEDINFOPOINTER|C_ICONBLKPOINTER|C_BITBLKPOINTER|C_TITLEBUTTONSTRING);
  531.                 fix_object(ptr->tree, FALSE, FALSE);
  532.  
  533.                 if (ptr->style & W_CUSTOMWINDOW) {
  534.                     ptr->wind = tree_copy(WINDTREE, C_TEDINFOPOINTER|C_ICONBLKPOINTER|C_BITBLKPOINTER|C_TITLEBUTTONSTRING);
  535.  
  536.                     fix_object(ptr->wind, TRUE, FALSE);
  537.                     form_center(ptr->wind, &x2, &y2, &w2, &h2);
  538.  
  539.                     x2 += abs(ptr->wind->ob_spec.obspec.framesize);
  540.                     y2 += abs(ptr->wind->ob_spec.obspec.framesize);
  541.                     w2 -= abs(ptr->wind->ob_spec.obspec.framesize) * 2;
  542.                     h2 -= abs(ptr->wind->ob_spec.obspec.framesize) * 2;
  543.  
  544.                     wind_calc(WC_BORDER, /*ptr->kind,*/ 0, x2, y2, w2, h2, &x2, &y2, &w2, &h2);
  545.                 } else {
  546.                     form_center(ptr->tree, &x2, &y2, &w2, &h2);
  547.  
  548.                     x2 += abs(ptr->tree->ob_spec.obspec.framesize);
  549.                     y2 += abs(ptr->tree->ob_spec.obspec.framesize);
  550.                     w2 -= abs(ptr->tree->ob_spec.obspec.framesize) * 2;
  551.                     h2 -= abs(ptr->tree->ob_spec.obspec.framesize) * 2;
  552.  
  553.                     wind_calc(WC_BORDER, ptr->kind, x2, y2, w2, h2, &x2, &y2, &w2, &h2);
  554.                 }
  555.  
  556.                 x = (x != -1) ? x : x2;
  557.                 y = (y != -1) ? y : y2;
  558.                 w = (w != -1) ? w : w2;
  559.                 h = (h != -1) ? h : h2;
  560.             }
  561.  
  562.             ptr->size.g_x = x;
  563.             ptr->size.g_y = y;
  564.             ptr->size.g_w = w;
  565.             ptr->size.g_h = h;
  566.  
  567.             ptr->size.g_x += 1;
  568.             ptr->size.g_y += 1;
  569.             ptr->size.g_w -= 2;
  570.             ptr->size.g_h -= 2;
  571.  
  572.             if ((ptr->handle = WWindCreate(ptr)) < 0) {
  573.                 free(ptr);
  574. #ifdef DEBUG
  575.                 form_alert(1, "[3][Cannot create window:| |No free window handles.][ OK ]");
  576. #endif
  577.                 return NULL;
  578.             }
  579.  
  580.             if ((xaes.wind_center == XW_SCREENCENTER) ||
  581.                 (xaes.wind_center == XW_PHYSICCENTER)) {
  582.                 ptr->size.g_x = (((desk.g_w) - (ptr->size.g_w)) / 2);
  583.                 ptr->size.g_y = (((desk.g_h) - (ptr->size.g_h)) / 2);
  584.             }
  585.  
  586.             if (xaes.wind_center == XW_MOUSECENTER) {
  587.                 int x, y, d;
  588.  
  589.                 graf_mkstate(&x, &y, &d, &d);
  590.                 ptr->size.g_x = x - (ptr->size.g_w / 2);
  591.                 ptr->size.g_y = y - (ptr->size.g_h / 2);
  592.  
  593.                 if (ptr->size.g_x < 0)
  594.                     ptr->size.g_x = 0;
  595.  
  596.                 if (ptr->size.g_y < 0)
  597.                     ptr->size.g_y = 0;
  598.             }
  599.  
  600.             ptr->size.g_x += desk.g_x;
  601.             ptr->size.g_y += desk.g_y;
  602.  
  603.             WindowChain->prev = ptr;                    /* Insert window in chain */
  604.             ptr->next = WindowChain;
  605.             ptr->prev = NULL;
  606.             WindowChain = ptr;
  607.  
  608.             graf_growbox(desk.g_w / 2, desk.g_h / 2, 2, 2, ptr->size.g_x, ptr->size.g_y, ptr->size.g_w, ptr->size.g_h);
  609.  
  610.             if (info)
  611.                 WWindSet(ptr, WF_INFO, info);
  612.  
  613.             if (state & W_OPEN)
  614.                 if (!(WOpenWindow(ptr)))
  615.                     return NULL;
  616.  
  617.             {
  618.                 int x, y, w, h;
  619.  
  620.                 WWindGet(ptr, WF_WORKXYWH, &x, &y, &w, &h);
  621.  
  622.                 ptr->tree->ob_x = x;
  623.                 ptr->tree->ob_y = y;
  624.             }
  625.  
  626.             if (state & W_UNUNTOPPABLE)
  627.                 WWindSet(ptr, WF_UNUNTOPPABLE, 1);
  628.  
  629.             if (state & W_BEVENT)
  630.                 WWindSet(ptr, WF_BEVENT, 1);
  631.  
  632.             if (state & W_TIMER)
  633.                 WWindSet(ptr, WF_TIMER, 1);
  634.  
  635.             if (state & W_DIALOG)
  636.                 WWindSet(ptr, WF_DIALOG, 1);
  637.  
  638.             if (state & W_UNSIZABLE)
  639.                 WWindSet(ptr, WF_UNSIZABLE, 1);
  640.  
  641.             if (title)
  642.                 WWindSet(ptr, WF_NAME, title);
  643.  
  644.             ptr->minimum.g_x = ptr->size.g_x;
  645.             ptr->minimum.g_y = ptr->size.g_y;
  646.             ptr->minimum.g_w = ptr->size.g_w;
  647.             ptr->minimum.g_h = ptr->size.g_h;
  648.  
  649.             if (!(ptr->state & W_UNSIZABLE)) {
  650.                 ptr->maximum.g_w = desk.g_w;
  651.                 ptr->maximum.g_h = desk.g_h;
  652.             } else {
  653.                 ptr->maximum.g_w = ptr->minimum.g_w;
  654.                 ptr->maximum.g_h = ptr->minimum.g_h;
  655.             }
  656.  
  657.             if (style & W_CUSTOMWINDOW) {
  658.                 WCreateObject(WC_SLIDER, ptr->wind, 0, 150, 10, SLIDER_VER, 16, 28, 27, 26);
  659.                 WCreateObject(WC_SLIDER, ptr->wind, 0, 150, 10, SLIDER_HOR, 31, 30, 29, 12);
  660.             }
  661.  
  662.             vsl_color(VDIhandle, BLACK);
  663.  
  664.             msg_buf[0] = WM_CREATED;
  665.             msg_buf[1] = Ap_ID;
  666.             msg_buf[2] = 0;
  667.             msg_buf[3] = ptr->handle;
  668.             WMsgWindow(ptr, msg_buf);
  669.  
  670.             ptr->user = NULL;
  671.  
  672.             msg_buf[0] = WM_COPIED;
  673.             msg_buf[1] = Ap_ID;
  674.             msg_buf[2] = 0;
  675.             msg_buf[3] = ptr->handle;
  676.             WMsgWindow(ptr, msg_buf);
  677.  
  678.             return ptr;
  679.         } else {
  680. #ifdef DEBUG
  681.             form_alert(1, "[3][Cannot create window:| |No free memory.][ OK ]");
  682. #endif
  683.             return NULL;
  684.         }
  685.     }
  686.  
  687.     if (type == WC_SLIDER) {
  688.         SLIDER slider;
  689.         OBJECT *obj;
  690.         EXTINFO *ex;
  691.  
  692.         va_start(argptr, wi_gfield);
  693.         obj = va_arg(argptr, OBJECT *);
  694.         slider.slide_pos = va_arg(argptr, int);
  695.         slider.slide_max = va_arg(argptr, int);
  696.         slider.slide_tstep = va_arg(argptr, int);
  697.         slider.slide_type = va_arg(argptr, int);
  698.         slider.slide_increase = va_arg(argptr, int);
  699.         slider.slide_slider = va_arg(argptr, int);
  700.         slider.slide_track = va_arg(argptr, int);
  701.         slider.slide_decrease = va_arg(argptr, int);
  702.         va_end(argptr);
  703.  
  704.         if (((obj[slider.slide_increase].ob_type & 0xFF) == G_USERDEF) &&
  705.             ((obj[slider.slide_decrease].ob_type & 0xFF) == G_USERDEF) &&
  706.             ((obj[slider.slide_slider].ob_type & 0xFF) == G_USERDEF) &&
  707.             ((obj[slider.slide_track].ob_type & 0xFF) == G_USERDEF)) {
  708.             double sldperc = ((slider.slide_type == SLIDER_HOR) ? (double)(obj[slider.slide_slider].ob_width) : (double)(obj[slider.slide_slider].ob_height)) /
  709.                              ((slider.slide_type == SLIDER_HOR) ? (double)(obj[slider.slide_track].ob_width) : (double)(obj[slider.slide_track].ob_height));
  710.             int newpos     = (int)((double)(sldperc) * (double)(slider.slide_max));
  711.  
  712.             ex = (EXTINFO *)(obj[slider.slide_increase].ob_spec.userblk->ub_parm);
  713.             ex->te_slider = slider;
  714.             ex = (EXTINFO *)(obj[slider.slide_decrease].ob_spec.userblk->ub_parm);
  715.             ex->te_slider = slider;
  716.             ex = (EXTINFO *)(obj[slider.slide_slider].ob_spec.userblk->ub_parm);
  717.             ex->te_slider = slider;
  718.             ex = (EXTINFO *)(obj[slider.slide_track].ob_spec.userblk->ub_parm);
  719.             ex->te_slider = slider;
  720.  
  721.             if (slider.slide_type == SLIDER_HOR) {
  722.                 obj[slider.slide_slider].ob_x = 0;
  723.                 obj[slider.slide_slider].ob_width = obj[slider.slide_track].ob_width - (newpos + slider.slide_max);
  724.  
  725.                 if (obj[slider.slide_slider].ob_width < (gr_cw * 4))
  726.                     obj[slider.slide_slider].ob_width = (gr_cw * 4);
  727.             } else {
  728.                 obj[slider.slide_slider].ob_y = 0;
  729.                 obj[slider.slide_slider].ob_height = obj[slider.slide_track].ob_height - (newpos + slider.slide_max);
  730.  
  731.                 if (obj[slider.slide_slider].ob_height < gr_ch)
  732.                     obj[slider.slide_slider].ob_height = gr_ch;
  733.             }
  734.  
  735.             slider.slide_pos = 0;
  736.             slider.slide_step = ((long)((slider.slide_type == SLIDER_HOR) ? obj[slider.slide_track].ob_width : obj[slider.slide_track].ob_height) -
  737.                                        (((slider.slide_type == SLIDER_HOR) ? obj[slider.slide_slider].ob_width : obj[slider.slide_slider].ob_height) << 16)) /
  738.                                         (long) slider.slide_max;
  739.             slider.slide_acc = 0;
  740.  
  741.             ex = (EXTINFO *)(obj[slider.slide_increase].ob_spec.userblk->ub_parm);
  742.             ex->te_slider = slider;
  743.             ex = (EXTINFO *)(obj[slider.slide_decrease].ob_spec.userblk->ub_parm);
  744.             ex->te_slider = slider;
  745.             ex = (EXTINFO *)(obj[slider.slide_slider].ob_spec.userblk->ub_parm);
  746.             ex->te_slider = slider;
  747.             ex = (EXTINFO *)(obj[slider.slide_track].ob_spec.userblk->ub_parm);
  748.             ex->te_slider = slider;
  749.  
  750.             return ((void *) TRUE);
  751.         }
  752.  
  753. #ifdef DEBUG
  754.         form_alert(1, "[3][Slider not created:| |One or more objects are|not G_USERDEF type.][ OK ]");
  755. #endif
  756.         return ((void *) FALSE);
  757.     }
  758.  
  759.     if (type == WC_POPUP) {
  760.         POPUP popup;
  761.         OBJECT *obj;
  762.         EXTINFO *ex;
  763.         int object;
  764.  
  765.         va_start(argptr, wi_gfield);
  766.         obj = va_arg(argptr, OBJECT *);
  767.         object = va_arg(argptr, int);
  768.         popup.curr_sel = 0;
  769.         popup.sel_text = va_arg(argptr, char *);
  770.  
  771.         if ((obj[object].ob_type & 0xFF) == G_USERDEF) {
  772.             ex = (EXTINFO *)(obj[object].ob_spec.userblk->ub_parm);
  773.  
  774.             ex->te_popup = popup;
  775.  
  776.             return ((void *) TRUE);
  777.         }
  778.  
  779. #ifdef DEBUG
  780.         form_alert(1, "[3][Cannot create popup:| |One or more objects|are not G_USERDEF][ OK ]");
  781. #endif
  782.         return ((void *) FALSE);
  783.     }
  784.  
  785.     if (type == WC_LISTBOX) {
  786.     }
  787.  
  788.     return ((void *) FALSE);
  789. }
  790.  
  791. /*
  792.  *    This is a routine to let you top a window.
  793.  */
  794. GLOBAL void WTopWindow(WINDOW *win)
  795. {
  796.     if (!win) {
  797.         if ((win = WindowChain)->next)
  798.             while (win->next->next)
  799.                 win = win->next;
  800.         else
  801.             return;
  802.     }
  803.  
  804.     WWindSet(win, WF_TOP, win->handle);
  805. }
  806.  
  807. /*
  808.  *    This lets you manually specify the area of a window to be redrawn
  809.  */
  810. GLOBAL void WRedrawWindow(WINDOW *win, int x, int y, int w, int h)
  811. {
  812.     int msg_buf[8];
  813.  
  814.     if (win) {
  815.         msg_buf[0] = WM_REDRAW;
  816.         msg_buf[1] = Ap_ID;
  817.         msg_buf[2] = 0;
  818.         msg_buf[3] = win->handle;
  819.         msg_buf[4] = x;
  820.         msg_buf[5] = y;
  821.         msg_buf[6] = w;
  822.         msg_buf[7] = h;
  823.  
  824.         WMsgWindow(win, msg_buf);
  825.     }
  826. }
  827.  
  828. /*
  829.  *    This closes, deletes and frees all windows in the WindowChain.
  830.  */
  831. GLOBAL void WKillAllWindows(int check)
  832. {
  833.     WINDOW *win = WindowChain;
  834.     int msg_buf[8] = {WM_CLOSEALL, 0, 0, 0, 0, 0, 0, 0};
  835.     int msg_buf2[8] = {WM_PROGEND, 0, 0, 0, 0, 0, 0, 0};
  836.  
  837.     msg_buf[3] = check;
  838.  
  839.     if (win)
  840.         if ((WCallEtcDispatcher(msg_buf)) || check == K_NO_STOP) {
  841.             while (win->next) {
  842.                 win = win->next;
  843.                 WCloseWindow(win->prev, WC_NOTOBJECTABLE, K_NO_STOP);
  844.             }
  845.  
  846.             while (WindowChain->next)
  847.                 WKillWindow(WindowChain);
  848.  
  849.             WCallEtcDispatcher(msg_buf2);
  850.         }
  851.  
  852.     vswr_mode(VDIhandle, MD_XOR);
  853. }
  854.  
  855. /*
  856.  *    This closes a window, with a specific type of priority.
  857.  */
  858. GLOBAL void WCloseWindow(WINDOW *win, int message, int priority)
  859. {
  860.     int msg_buf[8];
  861.  
  862.     if (!win)
  863.         win = WindowChain;
  864.  
  865.     if (win)
  866.         if (win->next) {
  867.             msg_buf[0] = WM_CLOSED;
  868.             msg_buf[1] = Ap_ID;
  869.             msg_buf[2] = 0;
  870.             msg_buf[3] = win->handle;
  871.             msg_buf[4] = message;
  872.             msg_buf[5] = priority;
  873.  
  874.             WMsgWindow(win, msg_buf);
  875.         }
  876. }